package com.loadburn.heron.storage.sql;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * @author slacrey (scstlinfeng@yahoo.com)
 *         Date: 13-12-25
 */
public class PageImpl<T> implements Page<T>, Serializable {

    private static final long serialVersionUID = -6828426354654231223L;

    private final List<T> content = new ArrayList<T>();
    private final long total;
    private final int page;
    private final int size;

    public PageImpl(List<T> content, int page, int size, long total) {

        if (null == content) {
            throw new IllegalArgumentException("Content must not be null!");
        }
        this.content.addAll(content);
        this.total = total;
        this.page = page;
        this.size = size;

    }

    public PageImpl(List<T> content, int page, int size) {
        this(content, page, size, null == content ? 0 : content.size());
    }

    @Override
    public int getNumber() {
        return page;
    }

    @Override
    public int getSize() {
        return size;
    }

    @Override
    public int getOffset() {
        return page * size;
    }

    @Override
    public int getTotalPages() {
        return getSize() == 0 ? 0 : (int) Math.ceil((double) total / (double) getSize());
    }

    @Override
    public int getNumberOfElements() {
        return content.size();
    }

    @Override
    public long getTotalElements() {
        return total;
    }

    @Override
    public boolean hasPreviousPage() {
        return getNumber() > 0;
    }

    @Override
    public boolean isFirstPage() {
        return !hasPreviousPage();
    }

    @Override
    public boolean hasNextPage() {
        return (getNumber() + 1) * getSize() < total;
    }

    @Override
    public boolean isLastPage() {
        return !hasNextPage();
    }

    @Override
    public Iterator<T> iterator() {
        return content.iterator();
    }

    @Override
    public List<T> getContent() {
        return Collections.unmodifiableList(content);
    }

    @Override
    public boolean hasContent() {
        return !content.isEmpty();
    }
}
